/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.ipartek.formacion.gestformwww.modelo.clases;

import com.ipartek.formacion.gestformwww.modelo.ModeloCandidato;
import com.ipartek.formacion.gestformwww.modelo.ModeloContacto;
import com.ipartek.formacion.gestformwww.modelo.beans.*;
import com.ipartek.formacion.gestformwww.modelo.beans.FiltroConvocatoria;
import com.ipartek.formacion.gestformwww.modelo.beans.excepciones.GestorFormacionExcepcion;
import com.ipartek.formacion.gestformwww.modelo.interfaces.*;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.ResourceBundle;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * Clase que gestiona los accesos a datos para objetos de tipo Convocatoria
 * @author Cristina Santi
 */
public class SQLServerConvocatoriaDAO implements IConvocatoriaDAO {

    public final static String FIELD_ID = "ConId";
    public final static String FIELD_NOMBRE = "ConNom";
    public final static String FIELD_HORA_INICIO = "ConHoraInicio";
    public final static String FIELD_HORA_FIN = "ConHoraFin";
    public final static String FIELD_OBSERVACION = "ConObservacion";
    public final static String FIELD_LUGAR = "ConLugarImpart";
    public final static String FIELD_DURACION = "ConDuracion";
    public final static String FIELD_DURACION_MINS = "ConDuracionMinutos";
    public final static String FIELD_FECHA_INICIO_PREVISTA = "ConFchaInPrev";
    public final static String FIELD_FECHA_FIN_PREVISTA = "ConFchaFinPrev";
    public final static String FIELD_TIPO_CURSO_ID = "TipCurId";
    public final static String FIELD_CONV_ACTIVA = "ConActiva";
    public final static String FIELD_CURSO_ID = "CurId";
    public final static String FIELD_CURSO_NOMBRE = "CurNom";
    private static ResourceBundle rb;

    public int contarConvocatorias(FiltroConvocatoria filtro) throws GestorFormacionExcepcion {
        int registros = 0;

        Connection conexion = null;
        String sql = filtro.getSQL();

        try {
            conexion = SQLServerDAOFactory.conecta();
        } catch (SQLException ex) {
            Logger.getLogger(SQLServerConvocatoriaDAO.class.getName()).log(Level.SEVERE, null, ex);
            throw new GestorFormacionExcepcion(rb.getString("no-conexion"));
        }

        try {
            PreparedStatement stmt = conexion.prepareStatement(sql, ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
            ResultSet rs = stmt.executeQuery();

            if (rs.last()) {
                registros = rs.getRow();
            }
            stmt.close();
            rs.close();
        } catch (SQLException ex) {
            Logger.getLogger(SQLServerConvocatoriaDAO.class.getName()).log(Level.SEVERE, null, ex);
            throw new GestorFormacionExcepcion(rb.getString("no-sql"));
        } finally {
            SQLServerDAOFactory.desconecta(conexion);
        }

        return registros;
    }


    /*
     * Constructor sin parametros, que asigna al campo rb, el valor correspondiente
     * del pull del conexiones
     */
    public SQLServerConvocatoriaDAO() {
        rb = ResourceBundle.getBundle("com.ipartek.formacion.gestformwww.controlador.excepciones");
    }

    /*
     * Metodo que recibe un objeto Filtro, y ejecuta la sentencia Select asociada.
     * Genera un array de convocatorias, y lo devuelve.
     * Se almacena el numero de convocatorias devueltas en la variable numConvocatorias
     * @param FiltroConvocatoria filtro
     * @return ArrayList<Convocatoria> convocatorias
     */
    public ArrayList<Convocatoria> listarConvocatorias(FiltroConvocatoria filtro) throws GestorFormacionExcepcion {

        ArrayList<Convocatoria> convocatorias = new ArrayList<Convocatoria>();
        Connection conexion = null;
        Convocatoria convocatoria = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        int primerelemento = (filtro.getPagsiguiente() - 1) * filtro.getElementospag() + 1;
        int ultimoelemento = filtro.getPagsiguiente() * filtro.getElementospag();
        String sql = filtro.getSQL();
        try {
            conexion = SQLServerDAOFactory.conecta();
        } catch (SQLException ex) {
            Logger.getLogger(SQLServerConvocatoriaDAO.class.getName()).log(Level.SEVERE, null, ex);
            throw new GestorFormacionExcepcion(rb.getString("no-conexion"));
        }
        try {
            pstmt = conexion.prepareStatement(sql);
            rs = pstmt.executeQuery();
            while (rs.next()) {
                convocatoria = new Convocatoria();
                if (rs.getRow() >= primerelemento && rs.getRow() <= ultimoelemento) {
                    convocatoria = instanciarConvocatoria(rs);
                    convocatorias.add(convocatoria);
                }
            }
        } catch (SQLException ex) {
            Logger.getLogger(SQLServerConvocatoriaDAO.class.getName()).log(Level.SEVERE, null, ex);
            throw new GestorFormacionExcepcion(rb.getString("no-sql"));
        } finally {
            closeAll(pstmt, rs, conexion);
        }
        return convocatorias;
    }

    public ArrayList<Convocatoria> listarConvocatoriasCandidato(Integer idCandidato) throws GestorFormacionExcepcion {
        ArrayList<Convocatoria> convocatorias = new ArrayList<Convocatoria>();
        Connection conexion = null;
        Convocatoria conv = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        String sql = null;

        sql = "SELECT ConNom, ConFchaInPrev, ConFchaFinPrev, ConDuracion FROM CONVOCATORIA INNER JOIN CANDCONV ON Convocatoria.ConId=CandConv.ConId WHERE CandConv.CanId=" + idCandidato;

        try {
            conexion = SQLServerDAOFactory.conecta();
        } catch (SQLException ex) {
            Logger.getLogger(SQLServerCandidatoDAO.class.getName()).log(Level.SEVERE, null, ex);
            throw new GestorFormacionExcepcion(rb.getString("no-conexion"));
        }

        try {
            pstmt = conexion.prepareStatement(sql);
            rs = pstmt.executeQuery();
            while (rs.next()) {
                conv=new Convocatoria();
                conv.setConNom(rs.getString("ConNom"));
                conv.setConFechaInicioPrev(rs.getDate("ConFchaInPrev"));
                conv.setConFechaFinPrev(rs.getDate("ConFchaFinPrev"));
                conv.setConDuracion(rs.getInt("ConDuracion"));
                convocatorias.add(conv);
            }
        } catch (SQLException ex) {
            Logger.getLogger(SQLServerContactoDAO.class.getName()).log(Level.SEVERE, null, ex);
            throw new GestorFormacionExcepcion(rb.getString("no-sql"));
        } finally {
            closeAll(pstmt, rs, conexion);
        }

        return convocatorias;
    }

    /**
     * Crea una instancia de Curso con los datos obtenidos de la base de datos.
     * @author  Jorge
     * @param rs: Recibe un ResultSet con una posición concreta.
     * @return Devuelve una instancia de curso con los datos del ResultSet indicado.
     */
    private Convocatoria instanciarConvocatoria(ResultSet rs) throws GestorFormacionExcepcion {
        Convocatoria convocatoria = new Convocatoria();
        DAOFactory factoria = DAOFactory.getDAOFactory(DAOFactory.SQLSERVER);
        ITipoCursoDAO tipoDAO = factoria.getITipoCursoDAO();

        try {
            convocatoria.setConActiva(rs.getBoolean(FIELD_CONV_ACTIVA));
            convocatoria.setConDuracion(rs.getInt(FIELD_DURACION));
            convocatoria.setConDuracionMin(rs.getInt(FIELD_DURACION_MINS));
            convocatoria.setConFechaFinPrev(rs.getDate(FIELD_FECHA_FIN_PREVISTA));
            convocatoria.setConFechaInicioPrev(rs.getDate(FIELD_FECHA_INICIO_PREVISTA));
            convocatoria.setConHoraFin(rs.getString(FIELD_HORA_FIN));
            convocatoria.setConHoraInicio(rs.getString(FIELD_HORA_INICIO));
            convocatoria.setConLugarImpart(rs.getString(FIELD_LUGAR));
            convocatoria.setConNom(rs.getString(FIELD_NOMBRE));
            convocatoria.setConObservacion(rs.getString(FIELD_OBSERVACION));
            convocatoria.setCurID(rs.getInt(FIELD_CURSO_ID));
            convocatoria.setCurNom(rs.getString(FIELD_CURSO_NOMBRE));
            convocatoria.setConId(rs.getInt(FIELD_ID));
            convocatoria.setTipoCur(tipoDAO.buscarTipoCurso(rs.getInt(FIELD_TIPO_CURSO_ID)));


        } catch (SQLException ex) {
            Logger.getLogger(SQLServerConvocatoriaDAO.class.getName()).log(Level.SEVERE, null, ex);
            throw new GestorFormacionExcepcion(rb.getString("no-sql"));
        }
        return convocatoria;
    }
    /*
     * Metodo que se encarga de cerrar, los elementos necesarias para el acceso a datos
     * @param PreparedStatement pstmt
     * @param ResultSet rs
     * @param Connection conexion
     */

    public void closeAll(PreparedStatement pstmt, ResultSet rs, Connection conexion) {
        try {
            if (rs != null) {
                rs.close();
            }
            if (pstmt != null) {
                pstmt.close();
            }
            if (conexion != null) {
                SQLServerDAOFactory.desconecta(conexion);
            }
        } catch (SQLException ex) {
            Logger.getLogger(SQLServerConvocatoriaDAO.class.getName()).log(Level.SEVERE, null, ex);
        }

    }
    /*
     * Metodo que se encarga de insetar datos en la tabla convocatoria, desde una
     * convocatoria que le llega por parametro
     * @param Convocatoria conv
     * 
     */

    public int crearConvocatoria(Convocatoria conv) {
        Connection conexion = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        int conId = 0;
        try {

            try {
                conexion = SQLServerDAOFactory.conecta();
            } catch (SQLException ex) {
                try {
                    throw new GestorFormacionExcepcion(rb.getString("no-conexion"));
                } catch (GestorFormacionExcepcion ex1) {
                    Logger.getLogger(SQLServerConvocatoriaDAO.class.getName()).log(Level.SEVERE, null, ex1);
                }
            }
            String sql = "INSERT INTO CONVOCATORIA (ConNom, ConHoraInicio, ConHoraFin, ConObservacion, "
                    + "ConLugarImpart, ConDuracion, ConDuracionMinutos, ConFchaInPrev, ConFchaFinPrev, "
                    + "TipCurId, ConActiva, CurId) VALUES(?,?,?,?,?,?,?,?,?,?,?,?)";
            ps = conexion.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
            ps.setString(1, conv.getConNom());
            ps.setString(2, conv.getConHoraInicio());
            ps.setString(3, conv.getConHoraFin());
            ps.setString(4, conv.getConObservacion());
            ps.setString(5, conv.getConLugarImpart());
            ps.setInt(6, conv.getConDuracion());
            ps.setInt(7, conv.getConDuracionMin());
            ps.setTimestamp(8, (Timestamp) conv.getConFechaInicioPrev());
            ps.setTimestamp(9, (Timestamp) conv.getConFechaFinPrev());
            ps.setInt(10, conv.getTipoCursoId());
            ps.setBoolean(11, conv.isConActiva());
            ps.setInt(12, conv.getCurID());
            ps.executeUpdate();
            rs = ps.getGeneratedKeys();
            if (rs.next()) {
                conId = rs.getInt(1);
            }

        } catch (SQLException ex) {
            Logger.getLogger(SQLServerConvocatoriaDAO.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            try {
                rs.close();
            } catch (SQLException ex) {
                Logger.getLogger(SQLServerConvocatoriaDAO.class.getName()).log(Level.SEVERE, null, ex);
            }
            closeAll(ps, null, conexion);

        }

        return conId;

    }

    /**
     * Metodo que elimina una convocatoria de la base de datos, incluyendo los datos relacionados con esa convocatoria
     * @author:Jorge, Ainara, Enrique
     * @param Id del Convocatoria.
     */
    public void eliminarConvocatoria(int idConv) throws GestorFormacionExcepcion {
        PreparedStatement stmt = null;
        Connection con = null;
        ResultSet rs;
        ArrayList<Integer> idCandidatos;
        ModeloCandidato modelo = new ModeloCandidato();
        ModeloContacto modeloContacto = new ModeloContacto();
        try {
            con = SQLServerDAOFactory.conecta();
        } catch (SQLException ex) {
            Logger.getLogger(SQLServerConvocatoriaDAO.class.getName()).log(Level.SEVERE, null, ex);
            throw new GestorFormacionExcepcion(rb.getString("no-conexion"));
        }
        try {
            idCandidatos = new ArrayList<Integer>();
            //Seleccionamos los candidatos que pertenecen a esa convocatoria
            stmt = con.prepareStatement("SELECT CanId FROM CANDCONV WHERE ConId='" + idConv + "'");
            rs = stmt.executeQuery();
            while (rs.next()) {
                idCandidatos.add(rs.getInt("CanId"));
            }
            rs.close();
            //Llamamos al metodo eliminarCandConv para borrar los candidatos asociados a esa convocatoria
            for (int i = 0; i < idCandidatos.size(); i++) {
                modeloContacto.eliminarTodosContactosCandidato(idCandidatos.get(i), idConv);
                modelo.eliminarCandConv(idCandidatos.get(i), idConv);
            }
            //Borramos la convocatoria seleccionada.
            stmt = con.prepareStatement("DELETE FROM CONVOCATORIA WHERE ConId=" + idConv);
            stmt.executeUpdate();
        } catch (SQLException ex) {
            Logger.getLogger(SQLServerConvocatoriaDAO.class.getName()).log(Level.SEVERE, null, ex);
            throw new GestorFormacionExcepcion(rb.getString("no-sql"));
        } finally {
            closeAll(stmt, null, con);
        }
    }

    public int modificarConvocatoria(Convocatoria conv) {
        Connection conexion = null;
        PreparedStatement ps = null;
        try {
            conexion = SQLServerDAOFactory.conecta();
            String sql = "UPDATE CONVOCATORIA SET ConNom = ? , "
                    + "ConHoraInicio = ?, ConHoraFin = ? , ConObservacion = ?, "
                    + "ConLugarImpart = ?, ConDuracion = ?, ConDuracionMinutos = ?, "
                    + "ConFchaInPrev = ?, ConFchaFinPrev = ?, TipCurId = ? , "
                    + "ConActiva = ? ,CurId = ? "
                    + "WHERE ConId = " + conv.getConId();
            ps = conexion.prepareStatement(sql);
            ps.setString(1, conv.getConNom());
            ps.setString(2, conv.getConHoraInicio());
            ps.setString(3, conv.getConHoraFin());
            ps.setString(4, conv.getConObservacion());
            ps.setString(5, conv.getConLugarImpart());
            ps.setInt(6, conv.getConDuracion());
            ps.setInt(7, conv.getConDuracionMin());
            ps.setTimestamp(8, (Timestamp) conv.getConFechaInicioPrev());
            ps.setTimestamp(9, (Timestamp) conv.getConFechaFinPrev());
            ps.setInt(10, conv.getTipoCursoId());
            ps.setBoolean(11, conv.isConActiva());
            ps.setInt(12, conv.getCurID());
            ps.executeUpdate();
        } catch (SQLException ex) {
            try {
                throw new GestorFormacionExcepcion(rb.getString("no-conexion"));
            } catch (GestorFormacionExcepcion ex1) {
                Logger.getLogger(SQLServerConvocatoriaDAO.class.getName()).log(Level.SEVERE, null, ex1);
            }
        } finally {
            closeAll(ps, null, conexion);
        }
        return conv.getConId();
    }

    public boolean existeConvocatoria(int idConv) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public Convocatoria visualizarConvocatoria(int idConv) {

        Connection conexion = null;
        PreparedStatement ps = null;
        Convocatoria conv = new Convocatoria();
        ResultSet rs = null;
        try {

            try {
                conexion = SQLServerDAOFactory.conecta();
            } catch (SQLException ex) {
                try {
                    throw new GestorFormacionExcepcion(rb.getString("no-conexion"));
                } catch (GestorFormacionExcepcion ex1) {
                    Logger.getLogger(SQLServerConvocatoriaDAO.class.getName()).log(Level.SEVERE, null, ex1);
                }
            }
//        StringBuilder query=new StringBuilder();
//        query.append("SELECT ")
//                //.append(FIELD_ID)
//               // .append(", ")
//                .append(FIELD_NOMBRE)
//                .append(", ")
//                .append(FIELD_HORA_INICIO)
//                .append(", ")
//                .append(FIELD_HORA_FIN)
//                .append(", ")
//                .append(FIELD_OBSERVACION)
//                .append(", ")
//                .append(FIELD_LUGAR)
//                .append(", ")
//                .append(FIELD_DURACION)
//                .append(", ")
//                .append(FIELD_DURACION_MINS)
//                .append(", ")
//                .append(FIELD_FECHA_INICIO_PREVISTA)
//                .append(", ")
//                .append(FIELD_FECHA_FIN_PREVISTA)
//                .append(", ")
//                .append(FIELD_TIPO_CURSO_ID)
//                .append(", ")
//                .append(FIELD_CONV_ACTIVA)
//                .append(", ")
//                .append(FIELD_CURSO_ID)
//                .append(" FROM ")
//                .append("CONVOCATORIA")
//                .append(" WHERE ")
//                .append(FIELD_ID)
//                .append(" = ")
//                .append(idConv);

//            ps = SQLServerDAOFactory.conecta().prepareStatement(query.toString());
            String sql = "SELECT ConNom, ConHoraInicio, ConHoraFin, ConObservacion, ConLugarImpart, "
                    + "ConDuracion, ConDuracionMinutos, ConFchaInPrev, ConFchaFinPrev, "
                    + "Convocatoria.TipCurId, ConActiva, Convocatoria.CurId, CurNom "
                    + "FROM Convocatoria INNER JOIN Curso ON Convocatoria.CurId = Curso.CurId "
                    + "WHERE ConId = " + idConv;

            ps = conexion.prepareStatement(sql);
            rs = ps.executeQuery();
            while (rs.next()) {
                conv.setConId(idConv);
                conv.setConActiva(rs.getBoolean(FIELD_CONV_ACTIVA));
                conv.setConDuracion(rs.getInt(FIELD_DURACION));
                conv.setConDuracionMin(rs.getInt(FIELD_DURACION_MINS));
                conv.setConFechaFinPrev(rs.getDate(FIELD_FECHA_FIN_PREVISTA));
                conv.setConFechaInicioPrev(rs.getDate(FIELD_FECHA_INICIO_PREVISTA));
                conv.setConHoraFin(rs.getString(FIELD_HORA_FIN));
                conv.setConHoraInicio(rs.getString(FIELD_HORA_INICIO));
                conv.setConLugarImpart(rs.getString(FIELD_LUGAR));
                conv.setConNom(rs.getString(FIELD_NOMBRE));
                conv.setConObservacion(rs.getString(FIELD_OBSERVACION));
                conv.setCurID(rs.getInt(FIELD_CURSO_ID));
                conv.setCurNom(rs.getString(FIELD_CURSO_NOMBRE));
                conv.setTipoCursoId(rs.getInt(FIELD_TIPO_CURSO_ID));

            }
        } catch (SQLException ex) {
            Logger.getLogger(SQLServerConvocatoriaDAO.class.getName()).log(Level.SEVERE, null, ex);

        } finally {
            closeAll(ps, null, conexion);
        }
        return conv;
    }

    public ArrayList<String> listarLugares() {

        ArrayList<String> lugares = new ArrayList<String>();
        Connection conexion = null;
        PreparedStatement ps = null;

        ResultSet rs = null;
        try {

            try {
                conexion = SQLServerDAOFactory.conecta();
            } catch (SQLException ex) {
                try {
                    throw new GestorFormacionExcepcion(rb.getString("no-conexion"));
                } catch (GestorFormacionExcepcion ex1) {
                    Logger.getLogger(SQLServerConvocatoriaDAO.class.getName()).log(Level.SEVERE, null, ex1);
                }
            }
            String query = "Select " + FIELD_LUGAR + " from CONVOCATORIA group by " + FIELD_LUGAR;

            ps = conexion.prepareStatement(query);
            rs = ps.executeQuery();
            while (rs.next()) {
                lugares.add(rs.getString(FIELD_LUGAR));
            }
        } catch (SQLException ex) {
            Logger.getLogger(SQLServerConvocatoriaDAO.class.getName()).log(Level.SEVERE, null, ex);

        } finally {
            closeAll(ps, null, conexion);
        }
        return lugares;
    }
}
